﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms.DataVisualization.Charting;

namespace EasyTrader.Signal
{
    public class DirectionDetector
    {
        private string m_Error = "True";
        public string Error
        {
            get { return m_Error; }
            set { m_Error = value; }
        }

        private int m_ForecastingRange = 0;
        public int ForecastingRange
        {
            get { return m_ForecastingRange; }
            set { m_ForecastingRange = value; }
        }

        private string m_ForecastingError = "False";
        public string ForecastingError
        {
            get { return m_ForecastingError; }
            set { m_ForecastingError = value; }
        }

        public DirectionDetector()
        {
            InitChartCtrl();
        }
        private System.Data.DataSet m_ForecastingDataSet = null;
        private System.Data.DataSet m_ErrorRangeDataSet = null;

        private System.Windows.Forms.DataVisualization.Charting.Chart m_ChartCtrl = null;
        private ETDataSet m_EeasyTraderDataSet = null;
        public EasyTrader.ETDataSet EeasyTraderDataSet
        {
            get { return m_EeasyTraderDataSet; }
            set { m_EeasyTraderDataSet = value; }
        }

        public void InitChartCtrl()
        {
            m_ChartCtrl = new System.Windows.Forms.DataVisualization.Charting.Chart();
            System.Windows.Forms.DataVisualization.Charting.ChartArea priceArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
            System.Windows.Forms.DataVisualization.Charting.Legend mainLegend = new System.Windows.Forms.DataVisualization.Charting.Legend();
            priceArea.Name = "Price";
            this.m_ChartCtrl.ChartAreas.Add(priceArea);
            mainLegend.BackColor = System.Drawing.Color.Transparent;
            mainLegend.DockedToChartArea = "Price";
            mainLegend.Name = "Legend1";
            System.Windows.Forms.DataVisualization.Charting.Series seriesRange = new System.Windows.Forms.DataVisualization.Charting.Series();
            System.Windows.Forms.DataVisualization.Charting.Series seriesPrice = new System.Windows.Forms.DataVisualization.Charting.Series();
            System.Windows.Forms.DataVisualization.Charting.Series seriesForcasting = new System.Windows.Forms.DataVisualization.Charting.Series();

            //seriesRange.BorderColor = System.Drawing.Color.Black;
            seriesRange.ChartArea = "Price";
            seriesRange.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Range;
            //seriesRange.Color = System.Drawing.Color.LightGreen;
            seriesRange.Legend = "Legend1";
            seriesRange.Name = "Range";
            seriesRange.YValuesPerPoint = 2;

            seriesPrice.ChartArea = "Price";
            seriesPrice.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            //seriesPrice.Color = System.Drawing.Color.Blue;
            seriesPrice.Legend = "Legend1";
            seriesPrice.Name = "Price";

            seriesForcasting.ChartArea = "Price";
            seriesForcasting.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            seriesForcasting.Legend = "Legend1";
            seriesForcasting.Name = "Forecasting";
            this.m_ChartCtrl.Series.Add(seriesRange);
            this.m_ChartCtrl.Series.Add(seriesPrice);
            this.m_ChartCtrl.Series.Add(seriesForcasting);
            this.m_ChartCtrl.Size = new System.Drawing.Size(1, 1);
        }

        public int SetChartData(int a_StartX, int a_EndX, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, bool a_AllowZero)
        {
            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (a_StartX < 0 || a_StartX >= rowCount || a_EndX < 0 || a_EndX >= rowCount)
                return -1;

            double val = 0;

            a_StartX = Math.Max(0, a_StartX);
            a_EndX = Math.Min(a_EndX, rowCount - 1);
            
            for (int i = a_StartX, j = 0; i <= a_EndX; i++, j++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        continue;
                    val = Convert.ToDouble(row[a_ColName]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (a_AllowZero == false && val == 0.0)
                        continue;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(j, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartData(int a_StartX, int a_EndX, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName1, string a_ColName2)
        {
            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (a_StartX < 0 || a_StartX >= rowCount || a_EndX < 0 || a_EndX >= rowCount)
                return -1;

            double val1 = 0.0;
            double val2 = 0.0;

            a_StartX = Math.Max(0, a_StartX);
            a_EndX = Math.Min(a_EndX, rowCount - 1);

            for (int i = a_StartX, j = 0; i <= a_EndX; i++, j = j + 2)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName1] == DBNull.Value || row[a_ColName2] == DBNull.Value)
                        continue;
                    val1 = Convert.ToDouble(row[a_ColName1]);
                    val2 = Convert.ToDouble(row[a_ColName2]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (val1 == 0.0 || val2 == 0.0)
                        break;
                    double midVal = (val1 + val2) / 2.0;
                    m_ChartCtrl.Series["Price"].Points.AddY(val2);
                    m_ChartCtrl.Series["Price"].Points.AddY(val1);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartData(int a_StartX, int a_EndX, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, double a_Open)
        {
            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (a_StartX < 0 || a_StartX >= rowCount || a_EndX < 0 || a_EndX >= rowCount || a_StartX >= a_EndX)
                return -1;

            double val = 0;
            m_ChartCtrl.Series["Price"].Points.AddY(a_Open);
            for (int i = a_StartX, j = 1; i <= a_EndX; i++, j++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        continue;
                    val = Convert.ToDouble(row[a_ColName]);
                    if (val == 0)
                        break;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(j, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartData(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName)
        {
            if (a_DataTable == null)
                return -1;

            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (rowCount == 0)
                return -1;
            

            double val = 0;
            for (int i = 0; i < rowCount; i++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        break;
                    val = Convert.ToDouble(row[a_ColName]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (val == 0)
                        break;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(i, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartData(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, int a_MaxBackRange)
        {
            if (a_DataTable == null)
                return -1;

            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (rowCount == 0)
                return -1;


            double val = 0;
            int startX = 0;
            if (rowCount > a_MaxBackRange)
                startX = rowCount - a_MaxBackRange;
            for (int i = startX, j = 0; i < rowCount; i++, j++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        break;
                    val = Convert.ToDouble(row[a_ColName]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (val == 0)
                        break;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(j, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartDataWithOpen(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null)
                return -1;

            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (rowCount == 0)
                return -1;


            double val = a_OpenVal;
            int startX = 0;
            if (rowCount > a_MaxBackRange)
                startX = rowCount - a_MaxBackRange;
            m_ChartCtrl.Series["Price"].Points.AddY(val);
            for (int i = startX, j = 1; i < rowCount; i++, j++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        break;
                    val = Convert.ToDouble(row[a_ColName]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (val == 0)
                        break;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(j, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public int SetChartDataWithOpen(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null)
                return -1;

            m_ChartCtrl.Series["Price"].Points.Clear();
            int rowCount = a_DataTable.GetRowCount();
            if (rowCount == 0)
                return -1;


            double val = a_OpenVal;
            int startX = Math.Max(0, a_EndX - a_MaxBackRange + 1);
            int endX = Math.Min(Math.Max(0, rowCount - 1), a_EndX);

            m_ChartCtrl.Series["Price"].Points.AddY(val);
            for (int i = startX, j = 1; i <= endX; i++, j++)
            {
                DataRow row = a_DataTable.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_ColName] == DBNull.Value)
                        break;
                    val = Convert.ToDouble(row[a_ColName]);
                    // 값이 0이라는 것은 값을 얻어오지 못했다는 것이므로 여기서 그만한다.
                    if (val == 0)
                        break;
                    //m_ChartCtrl.Series["Price"].Points.AddXY(j, val);
                    m_ChartCtrl.Series["Price"].Points.AddY(val);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
            return 1;
        }

        public void ShowForecasting(string a_RegressionType)
        {
            if (m_ChartCtrl.Series["Price"].Points.Count < 2)
                return;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");


        }

        public void SetForecasting(string a_RegressionType)
        {
            if (m_ChartCtrl.Series["Price"].Points.Count < 2)
                return;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");


        }

        // typeRegression is a string represented by one of the following strings:
        // "Linear", "Exponential", "Logarithmic", or "Power".
        // Polynomial is represented by an integer value in the form of a string.

        // Defining the typeRegression.
        // This Statement can also be represented by the statement typeRegression = "2";

        public ForecastingInfo GetForecastingInfoBeginEnd(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_StartX, int a_EndX, bool a_AllowZero)
        {
            SetChartData(a_StartX, a_EndX, a_DataTable, a_ColName, a_AllowZero);

            if (m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            if (a_StartX < 0 || a_StartX >= pointCount || a_EndX < 0 || a_EndX >= pointCount)
                return null;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = a_StartX;
            foreInfo.EndX = a_EndX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[a_StartX].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[a_StartX].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[a_EndX].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[a_EndX].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[a_StartX].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[a_EndX].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;

        }

        public int GetForecastingInfoBeginEnd(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_StartX, int a_EndX, bool a_AllowZero)
        {
            SetChartData(a_StartX, a_EndX, a_DataTable, a_ColName, a_AllowZero);

            if (m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            foreInfo.StartX = a_StartX;
            foreInfo.EndX = a_EndX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return 1;
        }

        public int GetForecastingInfoBeginEnd(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName1, string a_ColName2, string a_RegressionType, int a_StartX, int a_EndX)
        {
            SetChartData(a_StartX, a_EndX, a_DataTable, a_ColName1, a_ColName2);

            if (m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            foreInfo.StartX = a_StartX;
            foreInfo.EndX = a_EndX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return 1;
        }

        public ForecastingInfo GetForecastingInfo(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_MaxBackRange)
        {
            int result = SetChartData(a_DataTable, a_ColName, a_MaxBackRange);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = 0;
            foreInfo.EndX = pointCount - 1;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;

        }

        public ForecastingInfo GetForecastingInfoWithOpen(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_MaxBackRange, double a_OpenVal)
        {
            int result = SetChartDataWithOpen(a_DataTable, a_ColName, a_MaxBackRange, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = 0;
            foreInfo.EndX = pointCount - 1;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;

        }


        public ForecastingInfo GetForecastingInfoWithOpen(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            int result = SetChartDataWithOpen(a_DataTable, a_ColName, a_EndX, a_MaxBackRange, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = 0;
            foreInfo.EndX = pointCount - 1;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;

        }

        public ForecastingInfo GetForecastingInfo(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null)
                return null;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(rowCount -1, a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = 0;
            foreInfo.EndX = pointCount - 1;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if (a_EndX - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;

        }

        public ForecastingInfo GetForecastingInfo(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, bool a_AllowZero)
        {
            if (a_DataTable == null)
                return null;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(rowCount - 1, a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_AllowZero);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return null;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            try
            {
                // Create Forecasting Series.
                m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = 0;
            foreInfo.EndX = pointCount - 1;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if (a_EndX - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];
            return foreInfo;
        }

        public double GetForecastingY(EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null)
                return 0;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(Math.Max(0, rowCount - 1), a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return 0;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            double lastY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            return lastY;
        }

        public int GetForecastingInfo(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null || foreInfo == null)
                return -1;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(Math.Max(0,rowCount - 1), a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            //ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = startX;
            foreInfo.EndX = endX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if (a_EndX - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];

            return 1;
        }


        public int GetForecastingInfoWithOpen(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, double a_OpenVal)
        {
            if (a_DataTable == null || foreInfo == null)
                return -1;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(Math.Max(0, rowCount - 1), a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_OpenVal);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            //ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = startX;
            foreInfo.EndX = endX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if (a_EndX - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];

            return 1;
        }

        public int GetForecastingInfo(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, bool a_AllowZero)
        {
            if (a_DataTable == null || foreInfo == null)
                return -1;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(Math.Max(0, rowCount - 1), a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_AllowZero);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;
            try
            {
                // Create Forecasting Series.
                m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            //ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = startX;
            foreInfo.EndX = endX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if ((a_EndX + 1) - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];

            return 1;
        }

        // 이 함수는 선형회귀를 이용하여 평균값을 구하고 그 사이에서 가장 적절한 값을 취하여 가져온다.
        public double GetForecastingVal(ForecastingInfo foreInfo, EasyTrader.DataSet.ETDataTable a_DataTable, string a_ColName, string a_RegressionType, int a_EndX, int a_MaxBackRange, bool a_AllowZero)
        {
            if (a_DataTable == null || foreInfo == null)
                return -1.0;
            int rowCount = a_DataTable.GetRowCount();
            int startX = Math.Max(0, a_EndX - a_MaxBackRange);
            int endX = Math.Min(Math.Max(0, rowCount - 1), a_EndX);
            int result = SetChartData(startX, endX, a_DataTable, a_ColName, a_AllowZero);

            if (result < 0 || m_ChartCtrl.Series["Price"].Points.Count < 2)
                return -1.0;

            // Formula parameters
            string parameters = a_RegressionType + ',' + m_ForecastingRange + ',' + m_Error + ',' + m_ForecastingError;

            // Create Forecasting Series.
            m_ChartCtrl.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, parameters, "Price:Y", "Forecasting:Y,Range:Y,Range:Y2");

            int pointCount = m_ChartCtrl.Series["Price"].Points.Count;
            //ForecastingInfo foreInfo = new ForecastingInfo();
            foreInfo.StartX = startX;
            foreInfo.EndX = endX;
            foreInfo.ErrorStartHighY = m_ChartCtrl.Series["Range"].Points[0].YValues[0];
            foreInfo.ErrorStartLowY = m_ChartCtrl.Series["Range"].Points[0].YValues[1];
            foreInfo.ErrorEndHighY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[0];
            foreInfo.ErrorEndLowY = m_ChartCtrl.Series["Range"].Points[pointCount - 1].YValues[1];
            if ((a_EndX + 1) - a_MaxBackRange < 0)
                foreInfo.StartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            else
                foreInfo.StartY = m_ChartCtrl.Series["Forecasting"].Points[0].YValues[0];
            foreInfo.EndY = m_ChartCtrl.Series["Forecasting"].Points[pointCount - 1].YValues[0];
            foreInfo.PureStartY = m_ChartCtrl.Series["Price"].Points[0].YValues[0];
            foreInfo.PureEndY = m_ChartCtrl.Series["Price"].Points[pointCount - 1].YValues[0];

            // 중간 인덱스를 취하여 그 값을 반환해 준다. 전후 사정을 생각하여 중간값을 잡는 것이 가장 시세를 잘 반영한다고 볼 수 있다.
            int midIndex = (int)(pointCount / 2.0);
            double midVal = m_ChartCtrl.Series["Forecasting"].Points[midIndex].YValues[0];
            return midVal;
        }

        public void PutForecasting(EasyTrader.DataSet.ETDataTable a_DataTable, int a_StartX, int a_EndX, System.Windows.Forms.DataVisualization.Charting.Chart a_TargetChartCtrl, string a_ColName, string a_RegType, bool a_AllowZero)
        {
            if (a_DataTable == null || a_TargetChartCtrl == null)
                return;
            int result = SetChartData(a_StartX, a_EndX, a_DataTable, a_ColName, a_AllowZero);
            if (result < 0)
                return;
            SetChartDataOnTargetChart(a_TargetChartCtrl);
            SetForecasting(a_RegType);
            CopyForecasting(a_TargetChartCtrl, a_StartX);
        }

        private void CopyForecasting(System.Windows.Forms.DataVisualization.Charting.Chart a_TargetChartCtrl, int a_StartX)
        {
            if (a_TargetChartCtrl == null)
                return;
            int srcPointCount = m_ChartCtrl.Series["Forecasting"].Points.Count;
            int tgtPointCount = a_TargetChartCtrl.Series["Forecasting"].Points.Count;
            // 대상차트의 포인트를 모두 제거한다.
            a_TargetChartCtrl.Series["Forecasting"].Points.Clear();
            a_TargetChartCtrl.Series["ErrorRange"].Points.Clear();
            for (int i = 0, j = a_StartX; i < srcPointCount; i++, j++)
            {
                //if (i >= tgtPointCount)
                //    break;
                double foreVal = m_ChartCtrl.Series["Forecasting"].Points[i].YValues[0];
                //a_TargetChartCtrl.Series["Forecasting"].Points[j].YValues[0] = foreVal;
                a_TargetChartCtrl.Series["Forecasting"].Points.AddXY(j, foreVal);
                double rangeVal1 = m_ChartCtrl.Series["Range"].Points[i].YValues[0];
                double rangeVal2 = m_ChartCtrl.Series["Range"].Points[i].YValues[1];
            }
        }

        private void SetChartDataOnTargetChart(System.Windows.Forms.DataVisualization.Charting.Chart a_TargetChartCtrl)
        {
            if (a_TargetChartCtrl == null)
                return;
        }
        public void ExportChartData()
        {
            Series a_Series = m_ChartCtrl.Series["Forecasting"];
            if (a_Series == null)
                return;

            System.Data.DataSet seriesDataSet = m_ChartCtrl.DataManipulator.ExportSeriesValues(a_Series);
            seriesDataSet.WriteXml(a_Series.Name + ".xml");
            a_Series = m_ChartCtrl.Series["Range"];
            seriesDataSet = m_ChartCtrl.DataManipulator.ExportSeriesValues(a_Series);
            seriesDataSet.WriteXml(a_Series.Name + ".xml");
        }

        public void SendToDataset()
        {
            Series seriesForecasting = m_ChartCtrl.Series["Forecasting"];
            Series seriesErrorRange = m_ChartCtrl.Series["Range"];
            if (seriesForecasting == null || seriesErrorRange == null)
                return;
            m_ForecastingDataSet = m_ChartCtrl.DataManipulator.ExportSeriesValues(seriesForecasting);
            m_ErrorRangeDataSet = m_ChartCtrl.DataManipulator.ExportSeriesValues(seriesErrorRange);
        }

        public DataTable GetRangeTable()
        {
            if (m_ErrorRangeDataSet == null)
                return null;
            return  m_ErrorRangeDataSet.Tables[0];
        }

        public DataTable GetForecastingTable()
        {
            if (m_ForecastingDataSet == null)
                return null;

            return m_ForecastingDataSet.Tables[0];
        }

        public int GetCrossedCount(int a_CurIndex, EasyTrader.DataSet.ETDataTable a_Table, string a_FirstColName, string a_SecondColName, ref int a_MaxLen)
        {
            if (a_Table == null)
                return -1;
            int rowCount = a_Table.GetRowCount();
            if (rowCount == 0)
                return -1;
            DataRow row = a_Table.Rows[0];
            double bidsValue = Convert.ToDouble(row[a_FirstColName]);
            double asksValue = Convert.ToDouble(row[a_SecondColName]);
            double delta = bidsValue - asksValue;
            int oldTrend = GlobalVar.PriceFlat;
            if (delta > 0)
                oldTrend = GlobalVar.PriceUp;
            else if (delta < 0)
                oldTrend = GlobalVar.PriceDown;
            int crossCount = 0;
            a_MaxLen = 0;
            if (a_CurIndex <= 0)
                a_CurIndex = 0;
            if (a_CurIndex > 0)
            {
                a_CurIndex = Math.Min(a_CurIndex, rowCount - 1);
            }
            for (int i = 1; i < rowCount; i++)
            {
                row = a_Table.Rows[i];
                try
                {
                    // 값이 없을 경우는 넘어 간다.
                    if (row[a_FirstColName] == DBNull.Value)
                        continue;

                    bidsValue = Convert.ToDouble(row[a_FirstColName]);
                    asksValue = Convert.ToDouble(row[a_SecondColName]);

                    delta = bidsValue - asksValue;
                    int trend = GlobalVar.PriceFlat;
                    if (delta > 0)
                        trend = GlobalVar.PriceUp;
                    else if (delta < 0)
                        trend = GlobalVar.PriceDown;
                    if (oldTrend != GlobalVar.PriceFlat && trend != GlobalVar.PriceFlat &&
                        oldTrend != trend)
                    {
                        crossCount++;
                        a_MaxLen = 0;
                    }
                    a_MaxLen++;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }

            return crossCount;
        }
    }
}
